Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/学习/408/数据结构

4.1 串定义与基本操作

3 分钟阅读 · Note

目录树 578 篇

          • 3.1 栈
          • 4.1 串定义与基本操作
          • 5.1 树
          • 6.1 图的基本概念
          • 7.1 查找的基本概念
          • 8.1 排序基本概念
          • 第二章 线性表
          • 第一章 绪论
      • 论文
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗3.1 栈同一路径↗5.1 树同一路径↗6.1 图的基本概念同一路径↗7.1 查找的基本概念同一路径↗8.1 排序基本概念同一路径↗第二章 线性表同一路径
  • 4.1 串定义与基本操作

这章在大纲中是查找的一部分,考察的内容也比较少

4.1 串定义与基本操作

4.1.1 定义

![Pasted image 20251109161119](../../../_assets/d844e32-Pasted image 20251109161119.png)

4.1.2 基本操作

![Pasted image 20251109162052](../../../_assets/137acef-Pasted image 20251109162052.png)

求子串

![Pasted image 20251109164631](../../../_assets/3e537d0-Pasted image 20251109164631.png)

比较

![Pasted image 20251109164820](../../../_assets/a7b9e20-Pasted image 20251109164820.png)

定位

![Pasted image 20251109164856](../../../_assets/0e2be24-Pasted image 20251109164856.png)

字符集编码

![Pasted image 20251109162901](../../../_assets/271d533-Pasted image 20251109162901.png)

4.1.3 存储结构

顺序存储

![Pasted image 20251109163458](../../../_assets/262c504-Pasted image 20251109163458.png) ![Pasted image 20251109163804](../../../_assets/a4154a9-Pasted image 20251109163804.png)

链式存储

![Pasted image 20251109164010](../../../_assets/c987271-Pasted image 20251109164010.png)

4.2 模式匹配

在主串中寻找模式串相同的子串,并返回位置

4.2.1 朴素模式匹配算法(暴力)

![Pasted image 20251109165443](../../../_assets/e26baca-Pasted image 20251109165443.png)

与index算法相同,下面使用另一种方式实现: ![Pasted image 20251109165936](../../../_assets/f2917b6-Pasted image 20251109165936.png) ![Pasted image 20251109170001](../../../_assets/810f990-Pasted image 20251109170001.png) ![Pasted image 20251109170130](../../../_assets/a1c0f9b-Pasted image 20251109170130.png) 这种算法的思想和滑动窗口有点相似 ![Pasted image 20251109170203](../../../_assets/cdae11d-Pasted image 20251109170203.png)

4.2.2 KMP算法

朴素算法出现不匹配的位置的前面的主串字符的内容是已知的 ![Pasted image 20251109172811](../../../_assets/f808fc0-Pasted image 20251109172811.png)

![Pasted image 20251109172936](../../../_assets/ef9b52a-Pasted image 20251109172936.png) 也就是说,在第n个字符匹配失败的时候,仅仅根据模式串的内容就可以确定j指针指向的位置,这与主串无关。对于模式串‘abaabc’:

![Pasted image 20251109174202](../../../_assets/e0770cf-Pasted image 20251109174202.png)

获得n与j之间的对应关系(next数组),主串的指针就不会回溯,可以大大的提升效率

![Pasted image 20251109174402](../../../_assets/947839e-Pasted image 20251109174402.png)

性能对比

![Pasted image 20251109174551](../../../_assets/9354922-Pasted image 20251109174551.png)

求next数组(手算)

![Pasted image 20251109174915](../../../_assets/7570f74-Pasted image 20251109174915.png)![Pasted image 20251109174958](../../../_assets/8286828-Pasted image 20251109174958.png) ![Pasted image 20251109175105](../../../_assets/2de47a7-Pasted image 20251109175105.png) 换言之,无脑写next[1]=0,next[2]=1,剩下的部分分析

求nextval数组(优化next数组)

在这种情况下,i所指的字符一定不是a,j在移动到1后(a),一定会匹配失败 ![Pasted image 20251109180102](../../../_assets/c348a6d-Pasted image 20251109180102.png)

我们可以直接将next[3]的值改为0,跳过匹配失败的那一步: ![Pasted image 20251109180319](../../../_assets/740a57e-Pasted image 20251109180319.png)

nextval[1]无脑写0,只有匹配失败的字符和其next数组的字符相同时,才会优化: ![Pasted image 20251109181232](../../../_assets/a79e639-Pasted image 20251109181232.png)